<html t:ref="shell.html">
<li class="active" t:slot="nav3" t:ref=""/>
<div t:slot="body">
    <h4 style="margin-top: 0">1. <b>参数注入方式</b></h4>
    <p>
        在<a href="index.html">WebWheel</a>框架中，<a href="mvc.html#action-method">动作方法</a>可以接受HTTP参数的注入，
        注入的方式（地点）有三种：方法参数、实例属性和实例的setter方法，例如：
    </p>
    <pre class="prettyprint">public class AnAction {

    @WebParam
    public String a;

    @WebParam
    public void setB(String b) {}

    @Action(setterPolicy = SetterPolicy.ParameterAndField)
    public Object execute(@WebParam String c) {}
}</pre>
    <p>
        上述代码中，<code>execute</code>动作方法可以接受3个HTTP参数：<code>a</code>,<code>b</code>,<code>c</code>。
        使用<code>cn.webwheel.WebParam</code>注释对HTTP参数进行标示，当注入方式为方法参数和实例属性时，<code>WebParam</code>可以省略。
        可以设置动作方法的<code>Action</code>注释的<code>setterPolicy</code>参数，来控制注入方式，其取默认值时，
        将根据动作方法是否拥有方法参数来决定注入方式：如果拥有方法参数，则方法参数为注入地点；如果没有方法参数，则实例属性和实例setter为注入地点。
    </p>
    <p>
        <code>WebParam</code>的<code>value</code>参数决定HTTP参数的名称，默认为空则取注入地点的名称作为HTTP参数的名称：实例属性名、
        实例setter的属性名、方法参数的形参名称（框架依赖<a href="https://github.com/paul-hammant/paranamer">ParaNamer</a>来获取，
        可以实现在保留debug信息的字节码中获取形参名称）。
    </p>
    <h4>2. <b>参数设置器</b></h4>
    <p>
        <a href="mvc.html#setter">参数设置器</a>必须实现<code>cn.webwheel.Setter</code>接口
    </p>
    <pre class="prettyprint">//T为参数的类型
public interface Setter&lt;T> {
    T set(Object instance, Member member, Map&lt;String, Object> params, String paramName);
}</pre>
    <p>
        instance为动作类实例或者bean实例，为null时意为动作方法为静态java方法。
    </p>
    <p>
        member表示注入地点，可以为方法、属性，为null时意为动作方法才参数注入。
    </p>
    <p>
        params为所有的HTTP参数，key为参数的名称，value为参数的值，value有两种形式：String[]和FileEx[]，前者代表文本参数，
        后者代表上传的文件参数。
    </p>
    <p>
        paramName为HTTP参数的名称。
    </p>
    <p>
        set方法的返回值为注入的参数对象值，当动作方法拥有参数注入点时使用。
    </p>
    <h4>3. <b>内置参数注入器</b></h4>
    <p>
        <a href="index.html">WebWheel</a>框架内置了一些常用的参数设置器并在<code>Main.init()</code>方法中进行了类型绑定：
    </p>
    <pre class="prettyprint">set(String.class).by(new StringSetter());
set(String[].class).by(new StringArraySetter());

set(boolean.class).by(new BooleanSetter(Boolean.FALSE));
set(Boolean.class).by(new BooleanSetter(null));
set(boolean[].class).by(new BooleanArraySetter());

set(byte.class).by(new ByteSetter((byte) 0));
set(Byte.class).by(new ByteSetter(null));
set(byte[].class).by(new ByteArraySetter());

set(short.class).by(new ShortSetter((short) 0));
set(Short.class).by(new ShortSetter(null));
set(short[].class).by(new ShortArraySetter());

set(int.class).by(new IntSetter(0));
set(Integer.class).by(new IntSetter(null));
set(int[].class).by(new IntArraySetter());

set(long.class).by(new LongSetter(0L));
set(Long.class).by(new LongSetter(null));
set(long[].class).by(new LongArraySetter());

set(float.class).by(new FloatSetter(0f));
set(Float.class).by(new FloatSetter(null));
set(float[].class).by(new FloatArraySetter());

set(double.class).by(new DoubleSetter(0.0));
set(Double.class).by(new DoubleSetter(null));
set(double[].class).by(new DoubleArraySetter());

set(File.class).by(new FileSetter());
set(File[].class).by(new FileArraySetter());

set(FileEx.class).by(new FileExSetter());
set(FileEx[].class).by(new FileExArraySetter());

set(new TypeLiteral&lt;Map&lt;String, Object>>(){}.getType()).by(new MapOSetter());

set(new TypeLiteral&lt;Map&lt;String, String>>(){}.getType()).by(new MapSSetter());
set(new TypeLiteral&lt;Map&lt;String, String[]>>(){}.getType()).by(new MapSASetter());

set(new TypeLiteral&lt;Map&lt;String, File>>(){}.getType()).by(new MapFSetter());
set(new TypeLiteral&lt;Map&lt;String, File[]>>(){}.getType()).by(new MapFASetter());

set(new TypeLiteral&lt;Map&lt;String, FileEx>>(){}.getType()).by(new MapFxSetter());
set(new TypeLiteral&lt;Map&lt;String, FileEx[]>>(){}.getType()).by(new MapFxASetter());</pre>
    <h4>4. <b>文件上传参数FileEx</b></h4>
    <p>
        <code>cn.webwheel.FileEx</code>代表了文件上传
    </p>
    <pre class="prettyprint">public interface FileEx {
    //获得文件对象，存储在临时文件
    File getFile();

    //获得文件名，浏览器端选择的文件名称
    String getFileName();

    //获得上传的文件类型MIME
    String getContentType();

    //获得无后缀的文件名
    String getSimpleFileName();

    //获得文件后缀
    String getExtension();

    //获得输入流
    InputStream getStream();

    //转为byte[]
    byte[] toBytes() throws IOException;

    //清理资源，一般无需调用
    void destroy();
}</pre>
    <div style="text-align: center">
        <a href="userguide.html">返回用户手册</a>
    </div>
</div>
</html>